from flask import Blueprint
from datetime import datetime
from flask import render_template, session, redirect, url_for, flash, request, jsonify
from flask_login import login_user, logout_user, login_required, current_user
from . import main
from .forms import Login, SearchBookForm, ChangePasswordForm, EditInfoForm, SearchStudentForm, NewStoreForm, StoreForm, BorrowForm2
from exts import db, login_manager
from models import Admin, Book, Inventory, Student, ReadBook
import time, datetime
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer

student = Blueprint("student", __name__, url_prefix="/student")


@student.route("/test")
def test():
    return "test"


def haveRead(read_book, book):
    if book in read_book:
        return True
    else:
        return False


# 机器学习推荐图书

def recommend(card_id):

    # 从数据库中导入数据信息

    # books = [
    #     "Python编程入门 数据结构算法 Python语言",
    #     "深度学习实战 Python编程入门 计算机视觉",
    #     "数据结构算法 算法导论 Python编程入门",
    #     "计算机网络操作系统 操作系统概论 数据结构算法"
    # ]

    print("start......")

    # 全部书籍对象
    all_books = Book.query.filter_by().all()

    print(all_books)
    # 导入用户已经阅读过的书籍记录
    user_read_books = ReadBook.query.filter_by(card_id=card_id).all()
    if len(user_read_books) == 0:
        return None

    print(user_read_books)

    read_books = []


    # read_books为已读书目的isbn
    for code in user_read_books:
        read_books.append(Book.query.filter_by(isbn=Inventory.query.filter_by(barcode=code.barcode).first().isbn).first())

    print(read_books)
    # 使用TF-IDF进行特征提取
    vectorizer = TfidfVectorizer()
    tfidf_matrix = vectorizer.fit_transform([book.descn for book in all_books])

    # 计算用户已读书籍的TF-IDF向量
    user_tfidf_vector = vectorizer.transform([book.descn for book in read_books])

    # 计算用户已读书籍与其他书籍的相似度
    cosine_similarities = cosine_similarity(user_tfidf_vector, tfidf_matrix)



    # # 使用TF-IDF进行特征提取
    # vectorizer = TfidfVectorizer()
    # tfidf_matrix = vectorizer.fit_transform(books)
    #
    # # 计算用户已读书籍的TF-IDF向量
    # user_tfidf_vector = vectorizer.transform(user_read_books)
    #
    # # 计算用户已读书籍与其他书籍的相似度
    # cosine_similarities = cosine_similarity(user_tfidf_vector, tfidf_matrix)

    # 获取推荐的书籍
    recommendations = []
    count = 5


    for idx, sim in enumerate(cosine_similarities[0]):
        if count > 0 and sim != 0:
            if not haveRead(read_books, all_books[idx]):
                recommendations.append((all_books[idx], sim))
                count = count-1
                print(count)

        # if idx not in [books.index(book) for book in user_read_books]:

    # 按相似度排序推荐书籍
    recommendations.sort(key=lambda x: x[1], reverse=True)

    # 输出推荐结果
    print("为用户推荐的书籍:")
    for idx, (book, sim) in enumerate(recommendations, 1):
        print("{}. {} (相似度: {:.2f})".format(idx, book, sim))

    # 取recommendations前几个
    # 按照一定的样式展示recommendations



    return recommendations



@student.route('/', methods=['GET', 'POST'])
def login():
    form = Login()
    if form.validate_on_submit():
        print(form.account.data)
        print(form.password.data)
        user = Student.query.filter_by(student_id=form.account.data, password=form.password.data).first()
        if user is None:
            print("账号或密码错误！")
            flash('账号或密码错误！')
            return redirect(url_for('.login'))
        else:
            print("账号或密码正确")
            login_user(user)
            session['admin_id'] = user.student_id
            session['name'] = user.student_name
            return redirect(url_for('.search_book'))

    # return render_template('main/test.html')
    print("not valid")
    return render_template('main/student-login.html', form=form)
#


@student.route('/index')
@login_required
def index():
    return render_template('main/student-index.html', name=session.get('name'))


@student.route('/logout')
@login_required
def logout():
    logout_user()
    flash('您已经登出！')
    return redirect(url_for('.login'))


@student.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
    form = ChangePasswordForm()
    if form.password2.data != form.password.data:
        flash(u'两次密码不一致！')
    if form.validate_on_submit():
        if current_user.verify_password(form.old_password.data):
            current_user.password = form.password.data
            db.session.add(current_user)
            db.session.commit()
            flash(u'已成功修改密码！')
            return redirect(url_for('.index'))
        else:
            flash(u'原密码输入错误，修改失败！')
    return render_template("main/student-change-password.html", form=form)


@student.route('/user/<id>')
@login_required
def user_info(id):
    user = Student.query.filter_by(student_id=id).first()
    return render_template('main/student-user-info.html', user=user, name=session.get('name'))


@student.route('/borrow/<card_id>', methods=['GET', 'POST'])
@login_required
def borrow(card_id):
    form = BorrowForm2()
    return render_template('main/student-borrow.html', card_id=card_id, name=session.get('name'), form=form)


@student.route('/search_book', methods=['GET', 'POST'])
@login_required
def search_book():  # 这个函数里不再处理提交按钮，使用Ajax局部刷新
    form = SearchBookForm()
    return render_template('main/student-search-book.html', name=session.get('name'), form=form)


@student.route('/recommend_book/<card_id>', methods=['GET', 'POST'])
@login_required
def recommend_book(card_id):
    rec = recommend(card_id)
    # if rec is None:
    #     return render_template('main/student-recommend-book.html')
    return render_template('main/student-recommend-book.html', name=session.get('name'), rec=rec)


@student.route('/find_stu_book/<card_id>', methods=['GET', 'POST'])
def find_stu_book(card_id):
    stu = Student.query.filter_by(card_id=card_id).first()
    today_date = datetime.date.today()
    today_str = today_date.strftime("%Y-%m-%d")
    today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
    if stu is None:
        return jsonify([{'stu': 0}])  # 没找到
    if stu.debt is True:
        return jsonify([{'stu': 1}])  # 欠费
    if int(stu.valid_date) < int(today_stamp)*1000:
        return jsonify([{'stu': 2}])  # 到期
    if stu.loss is True:
        return jsonify([{'stu': 3}])  # 已经挂失
    books = db.session.query(Book).join(Inventory).filter(Book.book_name.contains(request.form.get('book_name')),
        Inventory.status == 1).with_entities(Inventory.barcode, Book.isbn, Book.book_name, Book.author, Book.press).\
        all()
    data = []
    for book in books:
        item = {'barcode': book.barcode, 'isbn': book.isbn, 'book_name': book.book_name,
                'author': book.author, 'press': book.press}
        data.append(item)
    return jsonify(data)
